package ru.ksu.environment;

import universum.bi.Location;
import universum.engine.environment.IAvailableMessage;
import universum.engine.environment.IBroadcastingParams;
import universum.engine.environment.IEnvControlMessage;
import universum.engine.environment.IEnvironment;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class NarrowEnvironment implements IEnvironment {
    private final Map<Location, List<MsgContainer>> _messages = new HashMap<Location, List<MsgContainer>>();
    private int _curRoundNum;

    public String getName() {
        return "Narrow Environment";
    }
    public String getShortName(){return "narrowenvironment";}

    public int getVersion() {
        return 0;
    }

    public synchronized void addMessage(IEnvControlMessage msg, IBroadcastingParams params) {
        Location location = msg.getCreatedLocation();
        synchronized (_messages) {
            if (!_messages.containsKey(location)) _messages.put(location, new ArrayList<MsgContainer>());
            _messages.get(location).add(new MsgContainer(msg, _curRoundNum, msg.getAuthorID()));
        }
    }

    public synchronized List<IAvailableMessage> getMessages(Location pos, int callerID) {
        List<IAvailableMessage> result = new ArrayList<IAvailableMessage>();
        synchronized (_messages) {
            if (_messages.containsKey(pos)) {
                for (MsgContainer msg : _messages.get(pos)) if (msg.AuthorID != callerID) result.add(msg.Message.getPreview());
            } // else return empty list                       
        }
        return result;
    }

    public void preRound(int roundNumber) {
        _curRoundNum = roundNumber;
    }

    public void postRound() {
        synchronized (_messages) {
            for (Map.Entry<Location, List<MsgContainer>> pair : _messages.entrySet()) {
                int i = 0;
                while (i < pair.getValue().size()) {
                    MsgContainer msg = pair.getValue().get(i);
                    if (_curRoundNum - msg.RoundNumber > 2) pair.getValue().remove(msg);
                    else i++;
                }
            }
        }
        //ioUtility.getInstance().writeDebug("NarrowEnv: messages count = " + _messages.size() + " after " + _curRoundNum + " round");
    }

    private class MsgContainer {
        public MsgContainer(IEnvControlMessage message, int roundNumber, int authorID) {
            Message = message;
            RoundNumber = roundNumber;
            AuthorID = authorID;
        }

        public IEnvControlMessage Message;
        public int RoundNumber;
        public int AuthorID;
    }
}
